import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { getRepository, Repository } from 'typeorm';
import { isEmail, isEmpty } from 'class-validator';
import { UserEntity } from '../../entity/user.entity';
import { RoleEntity } from 'src/entity/role.entity';
import { UserRoleEntity } from 'src/entity/user.role.entity';
import { ToolsService } from '../../tools/tools/tools.service'
import { CreateUserDto } from '../../modules/background/user/dto/createUser.dto'
import { UserListVo } from 'src/modules/background/user/vo/user.vo';
import { UserListDto } from 'src/modules/background/user/dto/user.list.dto';
import { StatusEnum } from 'src/enums/status.enum';
@Injectable()
export class UserService {
    constructor(
        @InjectRepository(UserEntity)
        private readonly userRepository: Repository<UserEntity>,
        @InjectRepository(RoleEntity)
        private readonly roleRepository: Repository<RoleEntity>,
        @InjectRepository(UserRoleEntity)
        private readonly userRoleRepository: Repository<UserRoleEntity>,
        private readonly toolsService: ToolsService
    ) { }
    // 增
    async add(data: CreateUserDto): Promise<string> {
        try {
            const { email } = data
            const isHave = await this.userRepository.findOne({ where: { email } })
            if (isHave) {
                const { email } = isHave;
                if (isEmail(email)) {
                    return '创建失败,已经存在该邮箱号';
                } else {
                    return '创建失败'
                }
            } else {
                const { roleIds, password = '123456' } = data
                const salt = this.toolsService.makeSalt() // 制作密码盐
                const hashPwd = this.toolsService.encryptPassword(password, salt);  // 加密密码
                const account = this.userRepository.create({
                    ...data,
                    password: hashPwd,
                    passSalt: salt,
                });
                const result = await this.userRepository.save(account);
                const { id } = result
                for (let i = 0; i < roleIds.length; i++) {
                    const roleAccount = this.userRoleRepository.create({
                        userId: Number(id),
                        roleId: Number(roleIds[i])
                    })
                    await this.userRoleRepository.save(roleAccount)
                }
                return '创建成功';
            }
        } catch (error) {
            return error
        }
    }
    // 删
    async remove(id: number): Promise<string> {
        const result = await this.userRepository.softDelete(id)//软删除数据库记录还在 但是查出来的是未删除的数据
        if (result) {
            return "删除成功"
        } else {
            return '删除失败/用户不存在'
        }
    }
    // 改
    async update(id: number, createUserDto: CreateUserDto): Promise<string> {
        try {
            const { mobile, username, status, isSuper, email, roleIds } = createUserDto
            const result = await this.userRepository.findOne(id);
            await this.userRepository.save(Object.assign(result, { mobile, username, status, isSuper, email }))
            await this.userRoleRepository.delete({ userId: id })
            for (let i = 0; i < roleIds.length; i++) {
                const roleAccount = this.userRoleRepository.create({
                    userId: id,
                    roleId: Number(roleIds[i])
                })
                await this.userRoleRepository.save(roleAccount)
            }
            return "更新成功"
        } catch (error) {
            return '更新失败'
        }

    }
    // 根据id 单条查询
    async findById(id: number): Promise<any> {
        // 根据id 用户查询
        const result = await this.userRepository.findOne(id);
        return result;
    }
    async findAll(data: UserListDto): Promise<UserListVo> {
        // pageNumber :当前页 pageSize:一页几条    v查询得用 or
        const { pageNum, pageSize, username = '', email = '', status, mobile = '' } = data
        const queryConditionList = []
        if (username) {
            queryConditionList.push("user.username LIKE :username");
        }
        if (email) {
            queryConditionList.push("user.email = :email", { email });
        }
        if (mobile) {
            queryConditionList.push("user.mobile = :mobile");
        }
        if (!isEmpty(status) && [StatusEnum.NORMAL, StatusEnum.FORBIDDEN].includes(Number(status))) {
            queryConditionList.push("user.status = :status");
        }
        const queryCondition = queryConditionList.join(" AND ")
        const [list, total] = await getRepository(UserEntity)
            .createQueryBuilder('user')
            .leftJoinAndMapMany('user.rolesList', UserRoleEntity, 'user_role', 'user.id = user_role.userId')//关联中间表
            .leftJoinAndMapMany('user.roles', RoleEntity, 'role', 'user_role.roleId = role.id')//中间表再关联角色表
            .andWhere(queryCondition, { username: `%${username}%`, email, mobile, status })
            .skip((pageNum - 1) * pageSize) // 跳过多少数据
            .take(pageSize) // 查询多少条数据
            .printSql() // 仅仅是打印sql语句,可以不写
            .getManyAndCount(); // 查询和返回条数
        let resultData = JSON.parse(JSON.stringify(list))
        resultData = resultData.map(item => {
            delete item.rolesList
            return item
        })
        return {
            data: resultData,
            total: total,
            pageNum,
            pageSize
        }
    }

}
